package com.leyou.item.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.enums.ExceptionEnums;
import com.leyou.common.exception.LyException;
import com.leyou.common.vo.PageResult;
import com.leyou.item.mapper.SkuMapper;
import com.leyou.item.mapper.SpuDetailMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.mapper.StockMapper;
import com.leyou.item.pojo.*;
import com.leyou.item.service.BrandService;
import com.leyou.item.service.CategoryService;
import com.leyou.item.service.GoodsService;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import tk.mybatis.mapper.entity.Example;

import java.beans.Transient;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品
 */
@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandService brandService;

    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private StockMapper stockMapper;

    //rabbitmq消息微服务
    @Autowired
    private AmqpTemplate amqpTemplate;


    @Override
    public PageResult<Spu> querySpuByPage(Integer page, Integer rows, Boolean saleable, String key) {
        //分页
        PageHelper.startPage(page, rows);
        //过滤
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        //搜索过滤
        if (StringUtils.isNotBlank(key)) {

            criteria.andLike("title", "%" + key + "%");
        }
        //上下架过滤
        if (saleable != null) {
            criteria.andEqualTo("saleable", saleable);
        }
        //默认排序
        example.setOrderByClause("last_update_time DESC");
        List<Spu> spus = spuMapper.selectByExample(example);

        if (CollectionUtils.isEmpty(spus)) {
            throw new LyException(ExceptionEnums.GOODS_NOT_FOND);
        }
        //解析分类和品牌的名称
        loadCategoryAndBrandName(spus);

        //解析分页结果
        PageInfo<Spu> pageInfo = new PageInfo<>(spus);

        return new PageResult<>(pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());
    }

    /**
     * 添加商品
     *
     * @param spu
     */
    @Override
    @Transactional
    public void saveGoods(Spu spu) {
        //添加spu
        spu.setId(null);
        spu.setCreateTime(new Date());
        spu.setLastUpdateTime(spu.getCreateTime());
        spu.setSaleable(true);//上架
        spu.setValid(false);//有效
        int count = spuMapper.insert(spu);
        if (count != 1) {
            throw new LyException(ExceptionEnums.Good_SAVE_ERROR);
        }

        //int a = 1/0;
        //添加spudetail
        SpuDetail spuDetail = spu.getSpuDetail();
        spuDetail.setSpuId(spu.getId());
        spuDetailMapper.insert(spuDetail);
        //添加sku和stock
        saveSkuAndStock(spu);
        //发送消息给mq
        amqpTemplate.convertAndSend("item.insert",spu.getId());

    }

    //抽取方法，添加sku和stock
    private void saveSkuAndStock(Spu spu) {
        int count;//添加sku
        List<Sku> skus = spu.getSkus();
        List<Stock> stockList = new ArrayList<>();//库存集合
        for (Sku sku : skus) {
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());
            sku.setSpuId(spu.getId());
            count = skuMapper.insert(sku);
            if (count != 1) {
                throw new LyException(ExceptionEnums.Good_SAVE_ERROR);
            }


            Stock stock = new Stock();
            stock.setStock(sku.getStock());
            stock.setSkuId(sku.getId());
            stockList.add(stock);
            //count = stockMapper.insert(stock);
            //if (count != 1) {
            //    throw new LyException(ExceptionEnums.Good_SAVE_ERROR);
            //}
        }
        //批量添加stock库存
        stockMapper.insertList(stockList);
    }

    /**
     * 查询商品详情
     *
     * @param spuId
     * @return
     */
    @Override
    public SpuDetail querySpuDetailById(Long spuId) {

        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(spuId);
        if (spuDetail == null) {
            throw new LyException(ExceptionEnums.GOODS_DETAIL_NOT_FOND);
        }
        return spuDetail;
    }

    @Override
    public List<Sku> querySkuBySpuId(Long spuId) {
        Sku sku = new Sku();
        //查询sku
        sku.setSpuId(spuId);

        List<Sku> skuList = skuMapper.select(sku);
        if (CollectionUtils.isEmpty(skuList)) {
            throw new LyException(ExceptionEnums.GOODS_SKU_NOT_FOND);
        }
        //查询库存
        //for(Sku s:skuList){
        //    Stock stock = stockMapper.selectByPrimaryKey(s.getId());
        //    if (stock==null){
        //        throw new LyException(ExceptionEnums.GOODS_STOCK_NOT_FOND)
        //    }
        //    s.setStock(stock.getStock());
        //}

        //获取sku集合的id
        List<Long> skuIdList = skuList.stream().map(s -> s.getId()).collect(Collectors.toList());
        //根据sku集合查询库存
        List<Stock> stocks = stockMapper.selectByIdList(skuIdList);
        //将库存转换为map集合mkey是skuid，value是库存量，方便给spu的stock属性赋值
        Map<Long, Integer> stockMap = stocks.stream().collect(Collectors.toMap(Stock::getSkuId, Stock::getStock));
        //遍历sku给每个sku的stock赋值
        skuList.forEach(s -> s.setStock(stockMap.get(s.getId())));
        return skuList;
    }

    //更新商品
    @Override
    @Transactional
    public void updateGoods(Spu spu) {
        //删除sku和stock
        Sku sku = new Sku();
        sku.setSpuId(spu.getId());
        //查询sku，因为库存需要skuid才能删除
        List<Sku> skuList = skuMapper.select(sku);
        if (!CollectionUtils.isEmpty(skuList)) {
            skuMapper.delete(sku);
            //删除stock
            List<Long> idList = skuList.stream().map(s -> s.getId()).collect(Collectors.toList());
            stockMapper.deleteByIdList(idList);

        }
        //修改spu
        spu.setValid(null);
        spu.setSaleable(null);
        spu.setLastUpdateTime(new Date());
        spu.setCreateTime(null);
        //更新，后面加Selective的方法表示不更新null的字段
        int count = spuMapper.updateByPrimaryKeySelective(spu);
        if (count != 1) {
            throw new LyException(ExceptionEnums.GOODS_UPDATE_ERROR);
        }

        //修改detail
        count = spuDetailMapper.updateByPrimaryKeySelective(spu.getSpuDetail());
        if (count != 1) {
            throw new LyException(ExceptionEnums.GOODS_UPDATE_ERROR);
        }

        //新增sku和stock
        saveSkuAndStock(spu);

        //发送消息给mq
        amqpTemplate.convertAndSend("item.update",spu.getId());


    }

    /*
    查询spu
     */
    @Override
    public Spu querySpuById(Long id) {
        //查询spu
        Spu spu = spuMapper.selectByPrimaryKey(id);
        if (spu==null){
            throw new LyException(ExceptionEnums.GOODS_NOT_FOND);
        }
        //查询sku
        List<Sku> skuList = querySkuBySpuId(id);
        spu.setSkus(skuList);
        //查询详情
        SpuDetail spuDetail = querySpuDetailById(id);
        spu.setSpuDetail(spuDetail);
        return spu;
    }

    @Override
    public Sku querySkuById(Long skuId) {

        Sku sku = skuMapper.selectByPrimaryKey(skuId);
        if (sku==null){
            throw new LyException(ExceptionEnums.GOODS_SKU_NOT_FOND);
        }
        return sku;
    }

    //处理解析spu的分类名称和品牌名称
    private void loadCategoryAndBrandName(List<Spu> spus) {

        for (Spu spu : spus) {
            //处理分类名称

            List<String> collect = categoryService.queryByIds(Arrays.asList(spu.getCid1(),
                    spu.getCid2(),
                    spu.getCid3()))
                    .stream()
                    .map(e -> e.getName())
                    .collect(Collectors.toList());

            String cname = StringUtils.join(collect, "/");
            spu.setCname(cname);
            //处理品牌名称
            Brand brand = brandService.queryById(spu.getBrandId());
            spu.setBname(brand.getName());
        }

    }


}
